home *** CD-ROM | disk | FTP | other *** search
- DOS32 V0.1
-
- A 386 32 bit dos extender for Assembly Programmers.
-
-
-
- Written By Adam Seychell. (5 / SEP / 1993)
-
- email s921880@minyos.xx.rmit.oz.au
-
-
-
-
-
- Copying.
-
- Feel free to copy and distribute this DOS extender.
- Use it in your programs any way you wish. I am
- distributing this to get people more familiar with
- protected mode programming.
- However if you do make use of it in your program I would
- appreciate if you credit me for the dos extender. Also if
- you use it to write anything great could you send me a copy.
- of it. I have spent a lot of hours writting this DOS extender.
-
-
- ********* FEATURES **********
-
- * Supports DPMI ( windows and OS/2 compatibility !!! )
-
- * Supports XMS
-
- * Supports No memory mangers ( most powerful )
-
- * Data and code segment descriptors avalible for
- 1. Your ASM segment.
- 2. Flat memory.
- 3. Base memory.
- 4. An allocated extended memory block
- ( size is defined by you).
-
- * Functions to set/get protected mode interrupt
- descriptor vectors.
-
- * Calling real mode interrupts is nearly as easy as
- calling in real mode itself. Switches to V86 mode when
- called.
-
- * Supports the SYSTEM BIOS COPY EXTENDED MEMORY BLOCK
- function INT 15h, AH = 87h for real mode. So a real
- mode TSR that calls this BIOS function (eg. HIMEM.SYS )
- will be emulated the dos extender. This allows TSRs like
- disk caches to be running.
-
-
- ******** KNOWN PROGRAM BUGS ***************
-
- There is a problem with the BIOS int 15h ah = 87 emulation.
- Only HIMEM.SYS calls it to transfer a XMS block while MSDOS
- is loaded in the Upper Memeory Block. It seems to be called
- with the location of the GDT ( for int 15 ah=87 ) in the ROM
- area. This gives an invalid GDT.
- When DOS is loaded into convention memory everything work fine because
- HIMEM.SYS supplies a valid GDT to this call.
-
-
- Introduction.
-
- DOS32.ASM is a 386 protected mode initialise
- program. The purpose of it is to make protected mode
- programming very easy. When I was writing DOS32.ASM my aim was
- to use full 32bit power of the 386 while making it as easy as
- possible to program.
- The DOS32.ASM is meant to be assembled as an object
- file and then linked to you assembler program. You ASM file
- must follow the following rules. Again, I tried to make this
- simple as possible.
-
-
- * Requires a small include file to setup macros,
- structures ect.
- * You must have the code segment named CODE32 and a data
- segment named DATA32.
- * Never change the stack segment register, i.e. SS.
- * Pass V86 mode segment registers on stack when calling
- V86 mode. ( see below for details)
- * The first 32 bytes of the stack are reserved.
- i.e locations ss:[0] up to ss:[1Fh]
- * Must have a starting point called "START32:" in the
- code segment.
- * Requires you to load valid selectors in ES,GS,FS at
- startup
- * Must only terminate the program with INT 21h, AH = 4Ch.
-
-
- **** DETAILS ON WHAT DOS32 DOES. *****
-
- DOS32.ASM basicly contains code to set up segment descriptors
- in the LDT or GDT, enter/exit protected mode, allocated/free a
- extended memory block and call real mode interrupts. These
- parts of the DOS32.ASM will never have to be called directly
- form your program.
-
- Note. If operating under DPMI then all DPMI services will be
- available.
-
- When not operating under DPMI there are two services in the
- dos extender to set and get the protected mode interrupt
- vectors. These will work exactly the same as DPMI services.
-
- SET interrupt
- ax = 204h
- bl = interrupt number
- edx = offset
- cx = selector
- int 31h
- returns: carry set on error
-
- GET interrupt
- ax = 205h
- bl = interrupt number
- int 31h
- returns: edx = offset
- cx = selector
-
- Also the Programible Interrupt Controllers ( 8259) base vector
- values can be obtained from the DPMI Get Version function, int 31h
- ax = 400h. If not running under DPMI then only the PIC bases
- are returned.
- DH = master PIC ( pic 2 )
- DL = slave PIC ( pic 1 )
-
-
-
-
- AVAILABLE DESCRIPTORS .
- There are nine available descriptors for you program
- that DOS32.ASM initially sets up. The selector values for each
- descriptor is stored in the data segment under the labels:
-
-
- PSP_sel :Data descriptor for the Program Segment Prefix
- Base = the real mode PSP segment.
- Limit = 100h
-
- Data_sel :Data descriptor for the your data segment "DATA32"
- Base = the real mode data segment.
- Limit = 1MB
-
- Code32_sel :32 bit code descriptor for the your code segment "CODE32"
- Base = the real mode code segment.
- Limit = 1MB
-
- TheStack_sel :Data descriptor for the stack
- Base = the real mode stack segment.
- Limit = See DOS32.ASM
-
- XMS_sel :Data descriptor for the allocated extended memory
- Base = the base address of the block
- Limit = Size of allocated block ( see below)
-
- BASE_sel :Data descriptor for the free base memory
- Base = the unused base memory straight after
- MSDOS loads in you program. (see below)
- Limit = 1Mb
-
-
- VIDEO_sel :Data descriptor for the video area.
- Base = A0000h
- Limit = 20000h
-
- FLAT_DATA_sel :Data descriptor for a flat memory model
- Base = 0
- Limit = FFFFFFFFh
-
- FLAT_CODE32_sel :32 bit code descriptor for a flat memory model
- Base = 0
- Limit = FFFFFFFFh
-
-
-
- The first instruction of you program will be executed is
- at offset "start32:" in your code segment.
-
- Your program is initially started with DS pointed to your
- data segment ( DATA32 ) and ESP and SS setup for the stack.
- The stack size is given by the equate in DOS32.ASM "Normal_stack".
- I've set the value to 200h bytes, but can be changed if required.
-
-
- NOTE: Your program must load valid selectors into ES,FS,GS if
- it's going to use any of them.
-
- example
- ;----------------------------------------
- start32: ; starting point
- mov gs,[flat_sel]
- mov es,[flat_sel]
- mov fs,[xms_sel]
-
- ...
- ... You program
- ...
- ...
-
- mov ah,4ch ; terminate
- int 21h
- ;----------------------------------------
-
- One more feature with DOS32.ASM is that in the data segment
- there are four labels in the data segment with information
- about memory.
-
- 1) "Base_Segment" will contain a real mode segment value
- of the start of free base memory. i.e The value stored in
- this label * 16 = the base address of the BASE_sel descriptor.
-
- 2) "PSP_segment". The real mode segment vlaue of the
- program segment prefix.
-
- 3) "XMS_base". Contains the linear base address of the
- allocated extended memory block.
-
- 4) "XMS_usage". This location contains the size of the
- allocated extended memory block required by your program.
- DOS32.ASM will read the value of this Label and attempt to
- allocate that amount of memory. If there isn't a enough free
- memory then DOS32.ASM will allocate as mush as it can and
- return what was actually allocated back into this Label.
-
- Notes
- o The XMS_sel descriptor Limit is set to this value.
- o The Memory allocated will never be greater than
- lockable memory.
- o If the XMS driver nor DPMI is available then the
- entire extended memory will be allocated by the xms
- descriptor. base = 0100000h , limit = available ram.
- o If XMS_usage is zero then no memory will be
- allocated and the XMS_sel will point to a invalid
- descriptor.
-
-
-
-
-
-
- Calling a Real mode interrupt:
-
- This is one of the most useful features of DOS32.ASM. The
- way the interrupt is called is through the macro "DOSINT"
- followed by the interrupt number. This macro actually consists
- of two instructions, mov & int 20h ( see DOS32.INC).
- When the real mode interrupt is called, all the
- 32bit general registers and the 16bit flags ( except for ESP )
-
- are loaded with the same values they were in protected mode.
- Because in protected mode the segment registers cant be loaded
- with any value (except for valid selectors) a different method
- is used to pass the segment register values.
- The segment registers values MUST be passed from
- protected mode to the called real mode interrupt through the
- stack segment. This is located in the stack at the first 4
- dwords and has the following format.
-
- ss:[00h] holds the GS register
- ss:[04h] holds the FS register
- ss:[08h] holds the DS register
- ss:[0Ch] holds the ES register
-
- This is the easiest and most versatile way I could
- think how to do it. Using the stack instead of say a data
- segment don't require DS,ES,GS or FS segment registers to be
- loaded with a specific selector. This is because SS will
- always contain the stack selector. I have included a data
- structure to make it easier to load these locations ( see the
- file DOS32.INC ).
-
-
- eg . to print a string using dos func 9 int 21h
- ;---------------------------------------------------------
- mov SS:Real_DS ,seg test_message ; pass DS register
- mov ah,9
- mov dx,offset test_message
- dosint 21h
-
- mov ah,4ch ; Terminate program
- int 21h
-
- db test_mesg ' String message using dos func ah = 9 ',10,13,36
- ;---------------------------------------------------------
-
- Just like calling real mode int, all the general registers,
- flags and segment registers(on the stack segment) will be
- returned with the values after the real mode interrupt call.
-
-
- The only thing to left to say about the called real
- mode interrupt is that the stack is set up by DOS32.ASM and
- cant be altered throng your program. The real mode stack space
-
- is defined by an equate in DOS32.ASM called "V86_stack_size". It
- is initially set to 200h and shouldn't need to be changed. I
- thought this should be a safe value.
-
-
-
-
- **** I don't ever want to here of people complaining
- about the 640K limit for there own assembly programs !